/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package npuzzle;

import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;

/**
 * Componente de la interfaz que pinta el puzzle y maneja la animación de los 
 * cuadors moviéndose
 * @author JULIAN
 */
class PuzzleView extends JComponent implements MouseListener {

    /*
     * Estado actual del tablero
     */
    private PuzzleNode estado;
    /* 
     * Tamaño del tablero en casillas por lado
     */
    private int n;
    /*
     * Tamaño en pixeles de cada cuadro dibujado
     */
    private static final int TAM = 70;
    /* 
     * Imagen de fondo por default de los cuadros
     */
    public static Image defaultBg = new ImageIcon("cuadro.png").getImage();
    /*
     * Imagen de fondo de usa en cada cuadro este PuzzleView
     */
    private Image imagenCuadro;

   
   

    /*
     * Construye un nuevo objeto, inicializandolo con el tamaño adecuado, de
     * acuerdo al tamaño deseado y el tamaño de los cuadros.
     * @param n el tamaño deseado de cada lado del tablero
     * @param tileBg la imagen que se usará de fondo en cada cuadro. Si es null
     * se ocupa una por default
     * 
     */
    public PuzzleView(int n, PuzzleNode node, Image tileBg) {
        setPreferredSize(new Dimension(n * TAM, n * TAM));
        setSize(new Dimension(n * TAM, n * TAM));
        setFocusable(true);
        this.n = n;
        this.estado = node;
        if (tileBg == null) {
            this.imagenCuadro = defaultBg;
        } else {
            this.imagenCuadro = tileBg;
        }
        addMouseListener(this);

    }

    /*
     * Indica a la vista que de desea mover el cuadro libre a la dirección señalada.
     * Si la dirección es legal, se actualiza el estado del nodo
     * @param la dirección a la que se debe mover. Se usan las 
     * constantes de direcciones  definidas en la clase {@link PuzzleNode}
     */
    public void move(int dir) {

        PuzzleNode pn = estado.move(dir);
        if (pn != null) {
            estado = pn;
        }
        repaint();
    }

    public PuzzleNode getNode() {
        return estado;
    }

    public void setNode(PuzzleNode estado) {
        this.estado = estado;
    }

    /* Dibuja a partir del estado actual, todos los cuadros con su respectivo
     * número. Si hay una animación en progreso, el cuadro que debe moverse
     * se pintará con un offset indicado por los campos animOffsetX y animOffsetY
     */
    public void paint(Graphics g) {
        g.setColor(Color.darkGray);
        g.fillRect(0, 0, this.getWidth(), this.getHeight());
        g.setFont(new Font("Arial", Font.BOLD, 32));
        g.setColor(Color.white);
        int x = 0, y = 0, val;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if ((val = estado.getCasilla(i, j)) != 0) {

                    g.drawImage(imagenCuadro, x, y, null);
                    g.drawString("" + val, x + 20, y + 42);

                }
                x += TAM;
            }
            x = 0;
            y += TAM;
        }
    }

    @Override
    public void mouseClicked(MouseEvent e) {
    }

    /*
     * Determina si el cuadro sobre el cual se hizo click es capaz de moverse
     * hacia alguno de las 4 direcciones y de ser así, hace la petición
     * de movimiento a la vista.
     */
    @Override
    public void mousePressed(MouseEvent e) {

        int i = e.getY() / TAM;
        int j = e.getX() / TAM;
        if (i != 0) {
            if (estado.getCasilla(i - 1, j) == 0) {
                move(PuzzleNode.UP);
            }
        }
        if (i != n - 1) {
            if (estado.getCasilla(i + 1, j) == 0) {
                move(PuzzleNode.DOWN);
            }
        }
        if (j != 0) {
            if (estado.getCasilla(i, j - 1) == 0) {
                move(PuzzleNode.LEFT);
            }
        }
        if (j != n - 1) {
            if (estado.getCasilla(i, j + 1) == 0) {
                move(PuzzleNode.RIGHT);
            }
        }

    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }

    
}
